package com.yonyou.ucf.mdf.app.extend.event;

import com.google.common.collect.Sets;
import com.yonyou.iuap.event.util.StringResponseUtil;
import com.yonyou.ucf.mdf.app.extend.event.eeac.api.YpdFieeacEventExecuteService;
import com.yonyou.ucf.mdf.app.extend.event.eeac.constant.EeacEventStatusEnum;
import com.yonyou.ucf.mdf.app.extend.event.eeac.constant.ExtBillCommonConstant;
import com.yonyou.ypd.bill.basic.entity.BillDOUtils;
import com.yonyou.ypd.bill.basic.entity.BillEntityInfo;
import com.yonyou.ypd.bill.basic.entity.IBillDO;
import com.yonyou.ypd.bill.basic.exception.YpdException;
import com.yonyou.ypd.bill.basic.json.JsonUtils;
import com.yonyou.ypd.bill.entity.manage.BillEntityInfoCache;
import com.yonyou.ypd.bill.infrastructure.service.api.IBillQueryRepository;
import com.yonyou.ypd.bill.infrastructure.service.api.IEnvService;
import com.yonyoucloud.iuap.ucf.mdd.starter.ucg.openapi.module.isv.event.ISVEventListener;
import com.yonyoucloud.iuap.ucf.mdd.starter.ucg.openapi.network.cryptor.EncryptionHolder;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.MapUtils;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * @Author: zhuyjh
 * @Date: 2024/3/6 10:16
 */
@Slf4j
@Component
@RequiredArgsConstructor
public class ISVEeacReceiveEvent  implements ISVEventListener<ISVDemoEventClass> {

    @Autowired
    private IBillQueryRepository billQueryRepository;

    @Autowired
    private IEnvService envService;

    @Autowired
    private YpdFieeacEventExecuteService ypdFieeacEventExecuteService;

    @Override
    public boolean onEvent(String type, ISVDemoEventClass event, EncryptionHolder holder) {
        //已经解密过了
        String content = event.getContent();
        if (StringUtils.isNotBlank(content)){
            log.info(">>>#onEvent#ISVEeacReceiveEvent接收到消息:{}", content);
            if (content != null && content.length() != 0) {
                receiveEEAC(event);
            }
            return true;
        }
        return false;
    }

    private String receiveEEAC(ISVDemoEventClass event){
        // 事件类型
        String eventType = event.getType();
        // 事件源
        String sourceId = event.getEventId();
        if (!"EEAC".equals(sourceId) && !"eeac_busievent_rep".equals(eventType)) {
            return StringResponseUtil.success("skip");
        }

        // 响应结果
        String userObject = event.getContent();
        List<Map> array = JsonUtils.jsonArray2PojoList(userObject,Map.class);
        if (array == null || array.isEmpty()) {
            return StringResponseUtil.success("skip");
        }
        try {
            for (int index = 0; index < array.size(); index++) {
                Map data = array.get(index);
                String code = MapUtils.getString(data, "code");
                String message = MapUtils.getString(data,"message");
                Map eventInfo = JsonUtils.json2Pojo(JsonUtils.toJsonString(data.get("eventInfo")), Map.class);
                String srcModule =  MapUtils.getString(eventInfo, "srcModule");
                if(!envService.getAppName().equals(srcModule)) {
                    continue;
                }
                // 单据ID
                String billId = MapUtils.getString(eventInfo,"srcBusiId");
                if(StringUtils.isBlank(billId)) {
                    throw new Exception("业务事项过账状态回写, 来源业务对象编码不能为空!");
                }
                // 版本号
                Long eeacVersion = MapUtils.getLong(eventInfo,"srcBillVersion");
                if (eeacVersion == null) {
                    throw new Exception("业务事项过账状态回写, 版本号不能为空!");
                }

                //实体uri
                if(ObjectUtils.isEmpty(eventInfo.get("srcExtraInfo"))) {
                    throw new Exception("业务事项过账状态回写, 扩展内容为空!");
                }
                String fullName = (String) JsonUtils.json2Pojo(eventInfo.get("srcExtraInfo").toString(), Map.class).get("fullName");
                BillEntityInfo billEntityInfo = BillEntityInfoCache.getInstance().getBillEntityInfo(fullName);

                //判断版本是否和单据的版本一致
                Map<String, Object> billInfo = null;
                try {
                    billInfo = billQueryRepository.queryByID(billEntityInfo, billId);
                } catch (Exception e) {
                    throw new Exception("业务事项过账状态回写失败, 获取单据信息异常：" + e.getMessage());
                }
                if(null == billInfo || billInfo.isEmpty()) {
                    throw new Exception("业务事项过账状态回写失败, 未获取到单据信息!");
                }

                IBillDO billDO = null;
                try {
                    billDO = BillDOUtils.createDOInstance(billEntityInfo);
                } catch (Exception e) {
                    throw new Exception("业务事项过账状态回写失败, 创建DO实例失败!");
                }
                if(ObjectUtils.isEmpty(billDO)) {
                    throw new Exception("业务事项过账状态回写失败, 未获取到DO实例!");
                }

                Object verseionObj = billInfo.get(ExtBillCommonConstant.FIELD_EEACVERSION);
                Long billEeacVersion = null;//数据版本
                if(ObjectUtils.isNotEmpty(verseionObj)) {
                    billEeacVersion = Long.valueOf(verseionObj.toString());
                }
                if(!eeacVersion.equals(billEeacVersion)) {
                    throw new Exception("业务事项过账状态回写失败, 过账数据版本不一致!");
                }

                EeacEventStatusEnum eeacEventStatusEnum = result(code, message);
                if(eeacEventStatusEnum == null){
                    continue;
                }

                //添加id
                billDO.setPrimaryKey(billId);

                //更新单据状态
                try {
                    ypdFieeacEventExecuteService.updateStatus(billDO, billEeacVersion, eeacEventStatusEnum.getValue());
                } catch (Exception e) {
                    log.error("业务事项过账状态回写失败, 更新状态异常：" + e.getMessage());
                    throw new YpdException("业务事项过账状态回写失败, 更新状态异常：" + e.getMessage());
                }
            }
        } catch (Exception e) {
            log.error("业务事项过账，异常信息："+ e.getMessage());
            return StringResponseUtil.fail(e.getMessage());
        }
        return StringResponseUtil.success();
    }

    @Override
    public int priority() {
        return ISVEventListener.super.priority()-102;
    }

    @Override
    public Set<String> supportTypes() {
        return Sets.newHashSet(ISVDemoEventExtendType.EEAC_EVENT);
    }

    @Override
    public Class<ISVDemoEventClass> getEventClass() {
        return ISVDemoEventClass.class;
    }

    /**
     * 200:成功
     * 204:不过账
     * 102 208 209 :忽略
     * 其他：过账失败
     * @param code
     * @param message
     * @return
     */
    private EeacEventStatusEnum result(String code, String message) {
        log.info("业务事项应答响应结果 {}", message);
        switch(code){
            case "200":
                return EeacEventStatusEnum.SUCCESS;
            case "204":
                return EeacEventStatusEnum.NO_POST;
            case "102":
            case "208":
            case "209":
                return null;
            default:
                return EeacEventStatusEnum.FAIL;
        }
    }
}